/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pl.edu.amu.wmi.kino.visualjavafx.visualjavafxproject.mimeFileType;

import java.io.IOException;
import java.util.logging.Logger;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import org.netbeans.core.spi.multiview.MultiViewDescription;
import org.netbeans.core.spi.multiview.MultiViewFactory;
import org.openide.cookies.EditCookie;
import org.openide.cookies.EditorCookie;
import org.openide.cookies.OpenCookie;
import org.openide.cookies.SaveCookie;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.text.CloneableEditorSupport;
import org.openide.text.DataEditorSupport;
import org.openide.util.Exceptions;
import org.openide.util.RequestProcessor;
import pl.edu.amu.wmi.kino.visualjavafx.javafxcodegenerators.api.JavaFXCodeGenerator;
import pl.edu.amu.wmi.kino.visualjavafx.model.api.ModelChangeEvent;
import pl.edu.amu.wmi.kino.visualjavafx.model.api.ModelChangeListener;
import pl.edu.amu.wmi.kino.visualjavafx.model.api.VisualJavaFxModelProvider;
import pl.edu.amu.wmi.kino.visualjavafx.model.objects.Application;
import pl.edu.amu.wmi.kino.visualjavafx.visualjavafxgui.editor.VisualJavaFxTextEditorDescription;
import pl.edu.amu.wmi.kino.visualjavafx.visualjavafxgui.editor.VisualJavaFxVisualEditorDescription;




/**
 *
 * @author psychollek
 */
public class VisualJavaFxFileEditorSupport extends DataEditorSupport implements ModelChangeListener, OpenCookie, EditorCookie, EditCookie{

    
    private static Logger LOG = Logger.getLogger(VisualJavaFxFileEditorSupport.class.getName());
    

    final MultiViewDescription[] descriptions = {
        new VisualJavaFxTextEditorDescription(this),
        new VisualJavaFxVisualEditorDescription(this)
    };


    static VisualJavaFxFileEditorSupport create(VisualJavaFxFileDataObject obj) {
        VisualJavaFxFileEditorSupport retVal = new VisualJavaFxFileEditorSupport(obj);
        return retVal;
    }

    private VisualJavaFxFileEditorSupport(VisualJavaFxFileDataObject obj) {
        super(obj, new VJFXFileEnv(obj));
    }

    @Override
    protected CloneableEditorSupport.Pane createPane() {
        return (CloneableEditorSupport.Pane)MultiViewFactory.
                createCloneableMultiView(descriptions, descriptions[0]);
    }

    @Override
    protected boolean notifyModified() {
        boolean retValue;
        retValue = super.notifyModified();
        if (retValue) {
            VisualJavaFxFileDataObject obj = (VisualJavaFxFileDataObject)getDataObject();
            obj.ic.add(env);
        }
        return retValue;
    }

    @Override
    protected void notifyUnmodified() {
        super.notifyUnmodified();
        VisualJavaFxFileDataObject obj = (VisualJavaFxFileDataObject)getDataObject();
        obj.ic.remove(env);
    }


    private static final class VJFXFileEnv extends DataEditorSupport.Env implements SaveCookie {

        private VJFXFileEnv(VisualJavaFxFileDataObject obj) {
            super(obj);
        }

        @Override
        public void save() throws IOException {
            VisualJavaFxFileEditorSupport ed = (VisualJavaFxFileEditorSupport)this.findCloneableOpenSupport();
            ed.saveDocument();
        }

        @Override
        protected FileObject getFile() {
            return super.getDataObject().getPrimaryFile();
        }
        
        @Override
        protected FileLock takeLock() throws IOException {
            return ((VisualJavaFxFileDataObject)super.getDataObject()).getPrimaryEntry().takeLock();
        }



    }

    private static boolean[] generating = {false};

    public void modelChanged(){
        if (!generating[0]){
            generating[0] = true;
            ModelToDocument m = new ModelToDocument(
                                    this.getDocument(),
                                    this.getDataObject().getLookup().lookup(
                                        VisualJavaFxModelProvider.class
                                        ),
                                    VisualJavaFxFileEditorSupport.generating
                                    );
            RequestProcessor.getDefault().post(m);
            notifyModified();
        }
    }

    @Override
    public void notifyModelChange(ModelChangeEvent evt) {
        this.modelChanged();
    }

}
class ModelToDocument implements Runnable {

    private Document doc = null;
    private Application app = null;
    private boolean[] generating = null;

    ModelToDocument(Document doc,VisualJavaFxModelProvider provider,boolean[] generating){
        this.doc = doc;
        this.app = provider.getModel();
        this.generating = generating;
    }

    @Override
    public void run() {
        this.generateFile();
        this.generating[0] = false;
    }

    private void generateFile(){
        try {
            String s = JavaFXCodeGenerator.generateCode(app);
            doc.remove(0, doc.getLength());
            doc.insertString(0, s, null);

        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        } catch (BadLocationException ex) {
            Exceptions.printStackTrace(ex);
        } finally {
            this.generating[0] = false;
        }
    }

}